#include "fstats.h"

void getTeamList(vector <match>& matchList, vector <team>& teamList) //Function to form the list of teams
{
	team temporaryTeam;
	bool newTeam;
	for(unsigned int i = 0; i < matchList.size(); i++)
	{
		newTeam = true; //At first we expect to get not yet recognized team for our list
		if (teamList.size() == 0) 
		{
			temporaryTeam.teamName = matchList[i].homeName; 
			teamList.push_back(temporaryTeam);
		}
		else
		{
			for (unsigned int j = 0; j < teamList.size(); j++)
			{
				if (matchList[i].homeName == teamList[j].teamName) 
				{
					newTeam = false; //Failed to get new team
					break;
				}
			}
			if (newTeam == true) //If new team is found
			{
				temporaryTeam.teamName = matchList[i].homeName; 
				teamList.push_back(temporaryTeam);
			}
		}
	}
}

void fillTeamList (vector <match>& matchList, vector <team>& teamList) //Info about finished matches flows to teamList
{
	tour temporaryTour;
	unsigned int matchListSize = matchList.size();
	unsigned int teamListSize = teamList.size(); 
	for(unsigned int i = 0; i < matchListSize; i++)
	{
		for(unsigned int j = 0; j < teamListSize; j++)
		{
			if (matchList[i].homeName == teamList[j].teamName) //Put the results of match to home team tourlist
			{
				temporaryTour.tourDate = matchList[i].matchDate;
				if (matchList[i].result == 1) temporaryTour.point = 0;
				else if (matchList[i].result == 0) temporaryTour.point = -2; 
				else temporaryTour.point = -3;
				teamList[j].tourList.push_back(temporaryTour);
			}
			if (matchList[i].visitorName == teamList[j].teamName) //Put the results of match to visitor team tourlist
			{
				temporaryTour.tourDate = matchList[i].matchDate;
				if (matchList[i].result == 1) temporaryTour.point = -3;
				else if (matchList[i].result == 0) temporaryTour.point = -2; 
				else temporaryTour.point = 0;
				teamList[j].tourList.push_back(temporaryTour);
			}
		}
	}
}

void fillTeamTourList (vector <team>& teamList)
{
	for(unsigned int i = 0; i < teamList.size(); i++)
	{
		teamList[i].tourList[0].pointSumm = teamList[i].tourList[0].point;
		for(unsigned int j = 1; j < teamList[i].tourList.size(); j++)
		{
			teamList[i].tourList[j].pointSumm = teamList[i].tourList[j-1].pointSumm + teamList[i].tourList[j].point;
		}
	}	
}

bool sortTeamPositions (currentTeamPosition a, currentTeamPosition b) //for std::sort
{ 
	return (a.pointSumm > b.pointSumm); 
}

void getCurrentTeamPosition (vector <team>& teamList)
{
	for(unsigned int j = 0; j < (teamList.size() - 1)*2; j++) //Over number of tours
	{
		vector <currentTeamPosition> teamCompare;
		currentTeamPosition temporaryTeamCompare;
		for(unsigned int i = 0; i < teamList.size(); i++) //Over teams
		{
			temporaryTeamCompare.teamName = teamList[i].teamName;
			temporaryTeamCompare.pointSumm = teamList[i].tourList[j].pointSumm;
			teamCompare.push_back(temporaryTeamCompare);
		}
		sort(teamCompare.begin(), teamCompare.end(), sortTeamPositions);//Sorting (every tour)
		for(unsigned int k = 0; k < teamList.size(); k++) //Remembering current positions
		{
			for (unsigned int l = 0; l < teamCompare.size(); l++)
			{
				if(teamList[k].teamName == teamCompare[l].teamName)
					teamList[k].tourList[j]. position = l; 
			}
		}
	}
}

bool compareDates (date date1, date date2)
{
	if ((date1.year == date2.year) && (date1.month == date2.month) && (date1.day == date2.day)) return true;
	else return false;
}

void returnPositionsToMatchList (vector <match>& matchList, vector <team>& teamList)
{
	unsigned int iteratorHome, iteratorVisitor, iteratorTour;
	for(unsigned int i = 0; i < matchList.size(); i++)
	{
		iteratorHome = 0;
		for(; !(matchList[i].homeName == teamList[iteratorHome].teamName); iteratorHome++); //Looking for home team
		iteratorTour = 0;
		for(; !(compareDates(matchList[i].matchDate, teamList[iteratorHome].tourList[iteratorTour].tourDate)); iteratorTour++);
		matchList[i].homePosition = teamList[iteratorHome].tourList[iteratorTour-1].position; //Fixing home team position
		iteratorVisitor = 0;
		for(; !(matchList[i].visitorName == teamList[iteratorVisitor].teamName); iteratorVisitor++); //Looking for visitor team
		iteratorTour = 0;
		for(; !(compareDates(matchList[i].matchDate, teamList[iteratorVisitor].tourList[iteratorTour].tourDate)); iteratorTour++);
		matchList[i].visitorPosition = teamList[iteratorVisitor].tourList[iteratorTour-1].position; //Fixing visitor team position
	}
}

void createEmptyResultingMatrix(vector <vector <resultingMatrixCell> >& resultingMatrix, unsigned short size)
{
	resultingMatrixCell clearCell;
	clearCell.gamePlayed = 0;
	clearCell.visitorWins = 0;
	clearCell.homeWins = 0;
	clearCell.draws = 0;
	vector <resultingMatrixCell> stringCell (size); //Making empty string of cells
	for(unsigned int i = 0; i < size; i++) stringCell[i] = clearCell;
	for(unsigned int i = 0; i < size; i++) //Filling the matrix with empty cells
	{
		resultingMatrix.push_back(stringCell);
	}
	resultingMatrixIsInitialised = true;
}

void fillResultingMatrix(vector <match>& matchList, vector <vector <resultingMatrixCell> >& resultingMatrix, unsigned short start_tour)
{
	for(unsigned int i = start_tour*teamList.size()/2; i < matchList.size(); i++)  //Filling every cell with match after
	{																			   //(start_tour*teamList.size()/2) matches
		(resultingMatrix[matchList[i].homePosition][matchList[i].visitorPosition].gamePlayed)++;
		if(matchList[i].result == 1) (resultingMatrix[matchList[i].homePosition][matchList[i].visitorPosition].homeWins)++;
		if(matchList[i].result == 0) (resultingMatrix[matchList[i].homePosition][matchList[i].visitorPosition].draws)++;
		if(matchList[i].result == -1) (resultingMatrix[matchList[i].homePosition][matchList[i].visitorPosition].visitorWins)++;
	}	
}

void normalizeResultingMatrix (vector <vector <resultingMatrixCell> >& resultingMatrix)
{
	unsigned short size = resultingMatrix[0].size();
	for(unsigned short i = 0; i < size; i++) //Looking through every matrix cell: normilization -> getting frequences
		{
			for(unsigned short j = 0; j < size; j++)
			{
				if (resultingMatrix[i][j].gamePlayed) 
				{
					resultingMatrix[i][j].homeWinsNorm = resultingMatrix[i][j].homeWins / resultingMatrix[i][j].gamePlayed;
					resultingMatrix[i][j].drawsNorm = resultingMatrix[i][j].draws / resultingMatrix[i][j].gamePlayed;
					resultingMatrix[i][j].visitorWinsNorm = resultingMatrix[i][j].visitorWins / resultingMatrix[i][j].gamePlayed;
				}
				else 
				{
					resultingMatrix[i][j].homeWinsNorm = resultingMatrix[i][j].drawsNorm = resultingMatrix[i][j].visitorWinsNorm = 0;
				}
			}
		}
}

void flushDynamicalArraysAndStoreInfo ()
{
	getTeamList(matchList, teamList);
	fillTeamList(matchList, teamList);
	fillTeamTourList(teamList);
	getCurrentTeamPosition(teamList);
	returnPositionsToMatchList(matchList, teamList);
	if (!resultingMatrixIsInitialised) createEmptyResultingMatrix(resultingMatrix, teamList.size());
	fillResultingMatrix(matchList, resultingMatrix, start_tour);
	matchList.erase(matchList.begin(), matchList.end());
	teamList.erase(teamList.begin(), teamList.end());
}
